<template>
  <!-- 节点 -->
  <div
    class="node-capsule-component"
    :style="{
      width: `${nodeWidth - 4}px`,
      height: `${nodeHeight - 4}px`,
    }"
  >
    <!-- 节点胶囊 -->
    <a-dropdown
      :trigger="[node.type !== 6 ? 'contextmenu' : '']"
      :overlay-style="{ width: '100px' }"
      :visible="node.id === menuOpenId && contextmenuVisible"
      @visibleChange="visibleChange"
    >
      <!-- 胶囊 -->
      <div class="dropdown-capsule">
        <!-- 禁用灰度 -->
        <div
          class="node-no-forbidden"
          :class="{ 'node-forbidden': node.data.forbidden }"
        ></div>
        <!-- 节点图标 -->
        <!-- <a-popover v-if="node.type === 1">
          <div slot="title" style="color: rgba(0, 0, 0, 0.65);">关键指数</div>
          <template slot="content">
            <p v-for="(item, index) in getDetailText(node)" :key="index">
              {{ item }}
            </p>
          </template>
          <div
            class="type-icon"
            :style="{
              'font-size': `${decimalZoomScale * 34}px`,
              height: `${nodeHeight - 6}px`,
              width: `${nodeHeight - 6}px`,
            }"
          >
            <a-icon-font class="type-icon-color" :type="iconInfo('icon')" />
          </div>
        </a-popover> -->
        <div
          class="type-icon"
          :style="{
            'font-size': `${decimalZoomScale * 34}px`,
            height: `${nodeHeight - 6}px`,
            width: `${nodeHeight - 6}px`,
          }"
        >
          <a-icon-font class="type-icon-color" :type="iconInfo('icon')" />
          <!-- <a-icon-font :type="groupIcon(node.type)"/> -->
        </div>

        <!-- 节点名称 -->
        <a-tooltip placement="top" :mouse-enter-delay="4">
          <template slot="title">
            <span>{{ node.name }}</span>
          </template>
          <!-- <div class="node-name" :style="{width: calcNameWidth + 'px', 'font-size': `${ decimalZoomScale * 12}px`, bottom:0}" @dblclick="doubleClickName(node, $event)"> -->
          <div
            class="node-name"
            :style="{
              width: calcNameWidth + 'px',
              'font-size': `${decimalZoomScale * 12}px`,
              top: nodeHeight + 3 + 'px',
            }"
          >
            <div
              class="normal-display"
              :class="{ 'node-forbidden-name': node.data.forbidden }"
            >
              {{ node.name }}
            </div>
            <a-icon-font
              v-if="comment"
              type="iconzujiandaohang-beifen3"
              @click.stop="showHideComment"
            />
          </div>
        </a-tooltip>
        <!-- 附表 toggle icon -->
        <slot
          v-if="!editStatus"
          name="toggleNode"
          class="menu-hover-ellipsis"
        ></slot>
      </div>
      <!-- 编辑菜单 -->
      <a-menu slot="overlay" @click="contextmenuVisible = false">
        <a-menu-item @click="popShow">数据详情 </a-menu-item>
      </a-menu>
    </a-dropdown>

    <!-- 注释 -->
    <!-- <div
      class="comment-container"
      :style="{
        left: `${(nodeWidth - 100) / 2}px`,
      }"
    >
      <a-textarea
        v-if="isCommentEditShow"
        ref="commentTextarea"
        v-model="commentValue"
        class="comment-textarea"
        auto-focus
        placeholder="请输入注释"
        :auto-size="{ minRows: 2, maxRows: 3 }"
        @mousedown.stop
        @click.stop
        @blur="saveComment"
      />
      <p
        v-if="isCommentReadShow"
        ref="commentTextarea"
        class="comment-readonly"
        @click.stop
      >
        {{ comment }}
      </p>
    </div> -->
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
import AddMenu from '@/components/studio/data/graph-compoments/AddMenu.vue'
import { queryUserDatalist } from '@/api/data-list'
import DataViewStore from '@/store/modules/dataview'
import {
  nodeIconWithBackGround,
  OperatorGroupIconEnum,
} from '@/components/studio/data/graph-compoments/node-icon-util'

@Component({
  components: {
    AddMenu,
  },
  directives: {
    focus: {
      inserted: (element: any) => {
        element.focus()
      },
    },
  },
})
export default class NodeCapsule extends Vue {
  // 节点高度
  @Prop({ type: Number, default: 0 }) nodeHeight!: number
  // 节点宽度
  @Prop({ type: Number, default: 0 }) nodeWidth!: number
  // 节点
  @Prop({ type: Object, default: () => ({}) }) node!: any
  // 网格宽
  @Prop({ type: Number, default: 0 }) gridSizeWidth!: number
  // 网格高
  @Prop({ type: Number, default: 0 }) gridSizeHeight!: number
  // 差值 宽
  @Prop({ type: Number, default: 0 }) differenceOfGridWidth!: number
  // 差值 高
  @Prop({ type: Number, default: 0 }) differenceOfGridHeight!: number
  // 缩放比例
  @Prop({ type: Number, default: 0 }) zoomScale!: number
  // 右键菜单打开node id
  @Prop({ type: Number, default: 0 }) menuOpenId!: number
  // 访客模式
  @Prop({ type: Boolean, default: 0 }) mode!: boolean
  // 节点注释
  @Prop({ type: String, default: '' }) comment!: string

  // 保存至数据管理,保存至数据源 弹窗显示
  public saveVisible: boolean = false
  // 保存type
  public saveType: number | null = null
  // 数据管理弹窗 form
  public dataMgtForm: any = {}
  // 新建分类是否显示
  public newClassVisible: boolean = false
  // 提示重复 弹窗显示
  public warningVisible: boolean = false
  // 用户数据列表(加载)
  public userDataList: Array<any> = []
  // 节点是否处于鼠标悬停状态
  public isNodeHovered: boolean = false
  // 右键菜单是否展示
  private contextmenuVisible: boolean = false

  // 是否显示编辑注释文本框
  private isCommentEditShow: boolean = false
  // 是否显示只读注释文本框
  private isCommentReadShow: boolean = false

  @Watch('menuOpenId')
  public closePopTable() {
    // this.popShow = false
  }

  private tableData: any = []
  private tableColumns: any = []
  private popVisible: boolean = false
  public async popShow() {
    this.$emit('node-event', { type: 'pop', value: true, nodeId: this.node.id })
  }

  public get columns() {
    return this.node?.data?.output[0]?.tableCols
  }

  public hasOutput(value: any) {
    if (value?.output?.length > 0) {
      return true
    }
    return false
  }

  // 加载数据  获取用户所有数据
  public LoadData() {
    queryUserDatalist({ data: { projectId: this.node.projectId } })?.then(
      (response: any) => {
        if (response.data.code === 100) {
          this.userDataList = response.data.result
        }
      }
    )
  }

  // 弹窗-新建分类
  public addClass() {
    this.$nextTick(() => {
      if (this.dataMgtForm.categoryId) {
        this.dataMgtForm.categoryId = undefined
      }
      if (this.dataMgtForm.categoryName) {
        this.dataMgtForm.categoryName = undefined
      }

      const name = this.$refs.classInput as HTMLElement // 使用ref需要用v-show代替v-if
      // @ts-ignore
      setTimeout(function () {
        name?.focus()
      }, 300) // 延迟focus，否则不生效
    })
    this.newClassVisible = true
  }

  /**
   * 分组 icon
   */
  public groupIcon(type: number) {
    return OperatorGroupIconEnum[type]
  }

  // 是否为自定义算子节点
  private get isOperatorNode() {
    return this.node.data.subTypeName === '通用算子'
  }

  // 可视化对比状态
  private get comparisonStatus() {
    return DataViewStore.comparisonStatus
  }

  // 可视化对比状态
  private get comparisonNodeIds() {
    return DataViewStore.comparisonNodeIds
  }

  private timer: any = null
  private editStatus: boolean = false
  private editName: string = ''
  private tooltipStyle: any = {
    background: '#fff',
  }

  // 小数 缩放比例
  private get decimalZoomScale() {
    return this.zoomScale / 100
  }

  /**
   * 节点图标 和 背景色
   */
  private iconInfo(type: string) {
    if (this.node.type === 2 && this.node.data.algName === 'JOIN') {
      return nodeIconWithBackGround(0, this.node.data.mod)[type]
    }
    return nodeIconWithBackGround(this.node.type, this.node.data.algType)[type]
  }

  private get calcNameWidth() {
    // 节点宽度 -  边框4 - 4padding - 节点图标宽度 - 节点状态宽度  - 间距
    return this.nodeWidth - 8 - (this.nodeHeight - 8) * 2 - 8
  }

  /**
   * 双击节点  编辑名称
   */
  public doubleClickName(task: any, $event: MouseEvent) {
    if (this.mode) {
      return
    }
    clearTimeout(this.timer)
    $event.stopPropagation()
    this.editName = this.node.name
    this.editStatus = true
    this.$emit('node-event', { type: 'name', value: true })
  }

  /**
   * 单击选择节点
   * @param $event
   */
  public selectNode($event: MouseEvent) {
    clearTimeout(this.timer)
    $event.stopPropagation()
    this.timer = setTimeout(() => {
      this.$emit('select-node', { node: this.node, e: $event })
    }, 200)
  }

  public visibleChange(value: boolean) {
    this.contextmenuVisible = value
    // if (value) {
    this.$emit('node-event', { type: 'menu', value, nodeId: this.node.id })
    // }
  }

  public getDetailText(node: any) {
    switch (node.data.algName) {
      case 'LINEARREGRE':
        return [
          `elastic_net=${node.data.elastic_net}`,
          `max_iter=${node.data.max_iter}`,
        ]
      case 'DBSCAN':
        return [
          `eps=${node.data.eps}`,
          `min_samples=${node.data.min_samples}`,
          `metric=${node.data.metric}`,
        ]
      case 'KMEANS':
        return [`k=${node.data.k}`]
      case 'ISO_FOREST':
        return [
          `n_estimators=${node.data.n_estimators}`,
          `max_samples=${node.data.max_samples}`,
          `contamination=${node.data.contamination}`,
        ]
      case 'FP_GROWTH':
        return [
          `min_frquency=${node.data.min_frquency}`,
          `min_support=${node.data.min_support}`,
          `min_confidence=${node.data.min_confidence}`,
        ]
      case 'PREFIX_SPAN':
        return [`min_support=${node.data.min_support}`]
      case 'PCA_DENSE':
        return [`dimesion_num=${node.data.dimension_num}`]
      case 'LLE':
        return [`dimesion_num=${node.data.dimension_num}`]
      case 'TSNE':
        return [`dimesion_num=${node.data.dimension_num}`]
      case 'LOGREGRE':
        return [
          `elastic_net=${node.data.elastic_net}`,
          `max_iter=${node.data.max_iter}`,
          `tolerance=${node.data.tolerance}`,
          `reg=${node.data.reg}`,
        ]
      case 'STAT_ANOMALY':
        return [`feature_col=${node.data.feature_col}`]
      default:
        return ''
    }
  }

  public showHideComment() {
    this.isCommentReadShow = !this.isCommentReadShow
  }
}
</script>

<style scoped lang="less">
/* 节点执行动画 unused */
@keyframes node-running {
  0% {
    background-position: 100% 50%;
  }

  100% {
    background-position: 0 50%;
  }
}
/* 执行节点 unused  */
.node-capsule-running {
  animation: node-running 1.4s ease infinite;
  background-size: 400% 100% !important;
}

/* 节点 胶囊 */
.node-capsule-component {
  align-content: center;
  background-color: #fff;
  box-sizing: border-box;
  justify-content: center;
  // padding: 7px 6px;
  position: absolute;
  z-index: 60;

  /* dropdown 中的节点胶囊 */
  .dropdown-capsule {
    align-items: center;
    cursor: pointer;
    display: flex;
    flex-direction: row;
    font-size: 14px;
    height: 100%;
    justify-content: center;
    text-align: center;
    user-select: none;
    width: 100%;
  }

  /* 尾部添加节点 */
  .after-add-node {
    background-color: #f0f2f5;
    height: 14px;
    line-height: 14px;
    position: absolute;
    right: -16px;
    transition: opacity 0.5s;
    width: 14px;

    &::before {
      background-color: transparent;
      content: '';
      height: 32px;
      left: -5px;
      position: absolute;
      width: 6px;
    }
  }

  // 禁用
  .node-no-forbidden {
    height: 0;
    left: 0;
    position: absolute;
    top: 0;
    width: 0;
  }

  /* 节点禁用灰度 */
  .node-forbidden {
    background-color: rgba(255, 255, 255, 0.5);

    cursor: not-allowed;
    height: 100%;
    width: 100%;
  }

  .node-forbidden-name {
    color: rgba(0, 0, 0, 0.5);
  }

  /* 节点图标 */
  .type-icon {
    align-items: center;
    // background-color: rgba(154, 162, 255, 1);
    // background-color: #d5d5d5;
    // border-radius: 50%;
    display: flex;
    flex-direction: row;
    justify-content: center;
    margin: 0 auto;

    // .type-icon-color {
    // color: #fff;
    // }
  }

  /* 节点name */
  .node-name {
    align-items: center;
    background-color: transparent;
    display: flex;
    height: 20px;
    justify-content: center;
    max-width: 100px;
    position: absolute;
    transform: translateY(-30%);

    .normal-display {
      overflow: hidden;
      text-align: left;
      text-overflow: ellipsis;
      white-space: nowrap;
      width: 100%;
    }

    /* 节点名称编辑 */
    .edit-name {
      height: 100%;
      padding: 0 2px;

      /deep/.ant-input {
        height: 100%;
        padding: 1px 2px;
        text-align: center;
        width: 130px;
      }
    }
  }

  /* 节点状态 */
  .status-icon-content {
    align-items: center;
    // border-radius: 50%;
    display: flex;
    justify-content: center;
    position: absolute;
    top: -15px;

    .status-icon {
      height: 18px;
      width: 18px;
    }
  }

  /* 对比图标 */
  .comparison-select {
    align-items: center;
    display: flex;
    justify-content: center;
    // border-radius: 50%;
  }
}

.comment-container {
  font-size: 11px;
  margin-top: 25px;
  position: absolute;
  width: 100px;

  .comment-textarea {
    font-size: 11px;
    resize: none;
  }

  .comment-readonly {
    color: #7a7f96;
    height: 55px;
    overflow: hidden;
    text-overflow: ellipsis;
    word-wrap: break-word;
  }
}
</style>
